home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / thesrc20.zip / fnmatch.c < prev    next >
C/C++ Source or Header  |  1995-01-26  |  5KB  |  183 lines

  1. /* Copyright (C) 1991 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. /*
  20. $Id: fnmatch.c 2.0 1995/01/26 16:31:07 MH Release MH $
  21. */
  22.  
  23.  
  24. /*  */
  25. #include <errno.h>
  26. #include "fnmatch.h"
  27.  
  28. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  29. extern int errno;
  30. #endif
  31.  
  32. /* Match STRING against the filename pattern PATTERN, returning zero if
  33.    it matches, nonzero if not.  */
  34. int
  35. fnmatch(pattern, string, flags)
  36.      char *pattern;
  37.      char *string;
  38.      int flags;
  39. {
  40.   register char *p = pattern, *n = string;
  41.   register char c;
  42.  
  43.   if ((flags & ~__FNM_FLAGS) != 0)
  44.     {
  45.       errno = EINVAL;
  46.       return -1;
  47.     }
  48.  
  49.   while ((c = *p++) != '\0')
  50.     switch (c)
  51.       {
  52.       case '?':
  53.         if (*n == '\0')
  54.           return FNM_NOMATCH;
  55.         else if ((flags & FNM_PATHNAME) && *n == '/')
  56.           return FNM_NOMATCH;
  57.         else if ((flags & FNM_PERIOD) && *n == '.' &&
  58.                  (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  59.           return FNM_NOMATCH;
  60.         else
  61.           ++n;
  62.         break;
  63.  
  64.       case '\\':
  65.         if (!(flags & FNM_NOESCAPE))
  66.           c = *p++;
  67.         if (*n++ != c)
  68.           return FNM_NOMATCH;
  69.         break;
  70.  
  71.       case '*':
  72.         if ((flags & FNM_PERIOD) && *n == '.' &&
  73.             (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  74.           return FNM_NOMATCH;
  75.  
  76.         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
  77.           if (((flags & FNM_PATHNAME) && *n == '/') ||
  78.               (c == '?' && *n == '\0'))
  79.             return FNM_NOMATCH;
  80.  
  81.         if (c == '\0')
  82.           return 0;
  83.  
  84.         {
  85.           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
  86.           for (--p; *n != '\0'; ++n)
  87.             if ((c == '[' || *n == c1) &&
  88.                 fnmatch(p, n, flags & ~FNM_PERIOD) == 0)
  89.               return 0;
  90.           return FNM_NOMATCH;
  91.         }
  92.  
  93.       case '[':
  94.         {
  95.           /* Nonzero if this if the sense of
  96.              the character class is inverted.  */
  97.           register int not;
  98.  
  99.           if (*n == '\0')
  100.             return FNM_NOMATCH;
  101.  
  102.           if ((flags & FNM_PERIOD) && *n == '.' &&
  103.               (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
  104.             return FNM_NOMATCH;
  105.  
  106.           not = *p == '!';
  107.           if (not)
  108.             ++p;
  109.  
  110.           c = *p++;
  111.           for (;;)
  112.             {
  113.               register char cstart = c, cend = c;
  114.  
  115.               if (!(flags & FNM_NOESCAPE) && c == '\\')
  116.                 cstart = cend = *p++;
  117.  
  118.               if (c == '\0')
  119.                 /* [ (unterminated) loses.  */
  120.                 return FNM_NOMATCH;
  121.  
  122.               c = *p++;
  123.               if ((flags & FNM_PATHNAME) && c == '/')
  124.                 /* [/] can never match.  */
  125.                 return FNM_NOMATCH;
  126.  
  127.               if (c == '-')
  128.                 {
  129.                   cend = *p++;
  130.                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
  131.                     cend = *p++;
  132.                   if (cend == '\0')
  133.                     return FNM_NOMATCH;
  134.                   c = *p++;
  135.                 }
  136.               if (*n >= cstart && *n <= cend)
  137.                 goto matched;
  138.  
  139.               if (c == ']')
  140.                 break;
  141.             }
  142.           if (!not)
  143.             return FNM_NOMATCH;
  144.           break;
  145.  
  146.         matched:;
  147.           /* Skip the rest of the [...] that already matched.  */
  148.           while (c != ']')
  149.             {
  150.               if (c == '\0')
  151.                 /* [... (unterminated) loses.  */
  152.                 return FNM_NOMATCH;
  153.  
  154.               c = *p++;
  155.               if (!(flags & FNM_NOESCAPE) && c == '\\')
  156.                 /* 1003.2d11 is unclear if this is right.  %%% */
  157.                 ++p;
  158.             }
  159.           if (not)
  160.             return FNM_NOMATCH;
  161.  
  162.           ++n;
  163.         }
  164.         break;
  165.  
  166.       default:
  167.         if ((flags & FNM_IGNORECASE))                     /* MH */
  168.           {                                               /* MH */
  169.            if (toupper(c) != toupper(*n++))               /* MH */
  170.               return FNM_NOMATCH;                         /* MH */
  171.           }                                               /* MH */
  172.         else                                              /* MH */
  173.            if (c != *n++)
  174.               return FNM_NOMATCH;
  175.  
  176.       }
  177.  
  178.   if (*n == '\0')
  179.     return 0;
  180.  
  181.   return FNM_NOMATCH;
  182. }
  183.